<?php

namespace app\api\controller;

use chillerlan\QRCode\QRCode;
use think\Image;
use think\Db;
use think\Log;
use OSS\OssClient;
use OSS\Core\OssException;
use Green\Request\V20180509 as Green;
use app\service\BaiduApi;

class Tool extends Common
{
    /**
     * 单图上传
     * @param int $thumb
     * @param int $water
     * @return \think\response\Json
     */
    public function imagesUpload($thumb = 0, $water = 0)
    {
        $switch = getenv('APP_OSS');

        $green = getenv('APP_GREEN');

        $config = Db::name('config_system')
            ->where(['title' => ['in', ['water', 'water_url']]])
            ->cache(86400)->column('title, content');

        $user_id = $this->member['id'] ?? '';

        if (!$switch) {
            $file = request()->file("image");

            if ($file) {
                $image = Image::open($file);
                if($image->width() / $image->height() > 4 || $image->height() / $image->width() > 4) {
                    return $this->miss('图片违规，不得涉黄');
                }
            } else {
                return json(['code' => 400, 'msg' => '请先上传图片']);
            }

            $path = ROOT_PATH . 'disk' . DS . 'uploads' . DS . 'images';

            $image = Image::open($file);
            $info = $file->validate(['ext' => 'jpg,png,gif,jpeg,JPG,PNG,GIF,JPEG'])->move($path);

            if ($info) {

                $img = '/disk/uploads/images/' . $info->getSaveName();
                $img = str_replace('\\', '/', $img);
                $dir = $path . DS . date('Ymd') . DS;

                // 图片检测
                if ($green) {
                    $image->thumb(1200, 1200)->save($dir . $info->getFilename());

                    $result = $this->green([['url'=>changeUrl($img, 1), 'width'=>$image->width(), 'height'=>$image->height()]]);

                    if ($result['code'] == 400) {
                        exit(json_encode(['code' => 400, 'msg' => $result['msg']]));
                    } else {
                        if ($result['msg']) exit(json_encode(['code' => 400, 'msg' => '图片检测违规，请重新上传']));
                    }
                }

                if ($config['water'] && $water && $config['water_url']) {

                    $water_url = trim($config['water_url'], '/');

                    $image->thumb(800, 800)->water($water_url, 6, 60)->save($dir . $info->getFilename());

                    $thumb1 = '';

                    if ($thumb) {
                        $thumb_ = explode('.', $info->getFilename());

                        $thumb1 = $thumb_[0] . '_thumb.' . $thumb_[1];
                        $image->thumb(800, 800)->water($water_url, 6, 60)->save($dir . $thumb_[0] . '_thumb.' . $thumb_[1]);
                    }
                } else {
                    if (!$green) {
                        $image->thumb(1200, 1200)->save($dir . $info->getFilename());
                    }

                    $thumb1 = '';
                    if ($thumb) {
                        $thumb_ = explode('.', $info->getFilename());

                        $thumb1 = $thumb_[0] . '_thumb.' . $thumb_[1];
                        $image->thumb(800, 800)->save($dir . $thumb_[0] . '_thumb.' . $thumb_[1]);
                    }
                }

                $thumb = $thumb1 ? '/disk/uploads/images/' . date('Ymd') . '/' . $thumb1 : '';

                $this->insertImage($img);
                return json(['code' => 200, 'data' => ['image' => $img, 'thumb' => $thumb]]);
            } else {
                return json(['code' => 400, 'msg' => $file->getError()]);
            }
        } else {

            $file = $_FILES['image'] ?? false;

            if ($file) {
                try {
                    $image = Image::open($file['tmp_name']);
                } catch (\Exception $e) {
                    return $this->miss('图片上传失败');
                }
                if($image->width() / $image->height() > 4 || $image->height() / $image->width() > 4) {
                    return $this->miss('图片违规，不得涉黄');
                }

                $name = $file['name'];
                $format = strrchr($name, '.');

                $new = sha1(date('YmdHis', time()) . uniqid()) . $format;

                if ($config['water'] && $water && $config['water_url']) {
                    $water_url = trim($config['water_url'], '/');
                    $image->thumb(1200, 1200)->water($water_url, 6, 60)->save(ROOT_PATH . 'disk' . DS . $new);
                } else {
                    $image->thumb(1200, 1200)->save(ROOT_PATH . 'disk' . DS . $new);
                }

                $localFile = str_replace('/index.php', '', $_SERVER['SCRIPT_FILENAME']) . '/disk/' . $new;

                // 图片检测
                if ($green) {
                    $result = $this->green([['url'=>changeUrl('/disk/'.$new, 1), 'width'=>$image->width(), 'height'=>$image->height()]]);

                    if ($result['code'] == 400) {
                        exit(json_encode(['code' => 400, 'msg' => $result['msg']]));
                    } else {
                        if ($result['msg']) {
                            unlink($localFile);
                            exit(json_encode(['code' => 400, 'msg' => '图片检测违规，请重新上传']));
                        }
                    }
                }

                $allow_type = ['.jpg', '.jpeg', '.gif', '.bmp', '.png', '.JPG', '.JPEG', '.GIF', '.PNG', '.BMP'];
                if (!in_array($format, $allow_type)) {
                    return json(['code' => 400, 'msg' => '文件格式不在允许范围内哦']);
                }

                $dir = 'disk/uploads/'.($user_id?$user_id.'/':'').'image/' . date("Ymd") . '/';
                $fileName = $dir . $new;

                $accessKeyId = getenv('OSS_KEYID');
                $accessKeySecret = getenv('OSS_KEYSECRET');
                $endpoint = getenv('OSS_ENDPOINT');
                $bucket = getenv('OSS_BUCKET');

                try {
                    $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);

                    $result = $ossClient->uploadFile($bucket, $fileName, $localFile);

                    if ($thumb) {
                        $thumb_ = explode('.', $new);
                        $thumb1 = $dir . $thumb_[0] . '_thumb.' . $thumb_[1];

                        $image->thumb(800, 800)->save(ROOT_PATH . 'disk' . DS . $thumb_[0] . '_thumb.' . $thumb_[1]);
                        
                        $thumb_localFile = str_replace('/index.php', '', $_SERVER['SCRIPT_FILENAME']) . '/disk/' . $thumb_[0] . '_thumb.' . $thumb_[1];

                        $result = $ossClient->uploadFile($bucket, $thumb1, $thumb_localFile);
                        unlink($thumb_localFile);
                    }
                } catch (OssException $e) {
                    return json(['code' => 400, 'msg' => $e->getMessage()]);
                }

                unlink($localFile);

                $this->insertImage('/' . $fileName);
                return json(['code' => 200, 'data' => ['image' => '/' . $fileName]]);
            }

            return json(['code' => 400, 'msg' => '文件不存在']);
        }
    }

    /**
     * 多图上传
     * @param int $thumb
     * @param int $water
     * @return \think\response\Json
     */
    public function imagesUploads($thumb = 0, $water = 0)
    {
        $switch = getenv('APP_OSS');
        $green = getenv('APP_GREEN');

        $config = Db::name('config_system')
            ->where(['title' => ['in', ['water', 'water_url', 'id']]])
            ->cache(86400)->column('title, content');

        if (!$switch) {
            $files = request()->file("image");

            if (!$files) return json(['code' => 400, 'msg' => '请先上传图片']);

            foreach ($files as $file) {
                $info = $file->validate(['ext' => 'jpg,png,gif,jpeg,JPG,PNG,GIF,JPEG']);
                if (!$info) return json(['code' => 400, 'msg' => $file->getError()]);

                $image = Image::open($file);
                if($image->width() / $image->height() > 4 || $image->height() / $image->width() > 4) {
                    return $this->miss('图片违规，不得涉黄');
                }
            }

            $imgs = '';
            $thumbs1 = '';
            $path = ROOT_PATH . 'disk' . DS . 'uploads' . DS . 'images';
            $dir = $path . DS . date('Ymd') . DS;
            $water_url = trim($config['water_url'], '/');
            $url = '/disk/uploads/images/' . date('Ymd') . '/';

            foreach ($files as $key => $file) {
                // 当move后临时文件也将不存在，故先打开临时图片将move
                $image = Image::open($file);
                $info = $file->move($path);

                if ($info) {
                    $img = '/disk/uploads/images/' . $info->getSaveName();
                    $img = str_replace('\\', '/', $img);

                    // 图片检测
                    if ($green) {
                        $image->thumb(1200, 1200)->save($dir . $info->getFilename());

                        $result = $this->green([['url'=>changeUrl($img, 1), 'width'=>$image->width(), 'height'=>$image->height()]]);

                        if ($result['code'] == 400) {
                            exit(json_encode(['code' => 400, 'msg' => $result['msg']]));
                        } else {
                            if ($result['msg']) exit(json_encode(['code' => 400, 'msg' => '图' . ($key + 1) . '检测违规，请重新上传']));
                        }
                    }

                    if ($config['water'] && $water && $config['water_url']) {

                        $image->thumb(800, 800)->water($water_url, 6, 60)->save($dir . $info->getFilename());

                        $imgs = $imgs ? $imgs . ',' . $img : $img;

                        if ($thumb) {
                            $thumb_ = explode('.', $info->getFilename());

                            $thumb1 = $thumb_[0] . '_thumb.' . $thumb_[1];
                            $image->thumb(800, 800)->water($water_url, 6, 40)->save($dir . $thumb_[0] . '_thumb.' . $thumb_[1]);

                            $thumbs1 = $thumbs1 ? $thumbs1 . ',' . $url . $thumb1 : $url . $thumb1;
                        }
                    } else {
                        if (!$green) {
                            $image->thumb(1200, 1200)->save($dir . $info->getFilename());
                        }

                        $imgs = $imgs ? $imgs . ',' . $img : $img;

                        if ($thumb) {

                            $thumb_ = explode('.', $info->getFilename());

                            $thumb1 = $thumb_[0] . '_thumb.' . $thumb_[1];
                            $image->thumb(800, 800)->save($dir . $thumb_[0] . '_thumb.' . $thumb_[1]);

                            $thumbs1 = $thumbs1 ? $thumbs1 . ',' . $url . $thumb1 : $url . $thumb1;
                        }
                    }
                } else {
                    return json(['code' => 400, 'msg' => $file->getError()]);
                }
            }

            $this->insertImage($imgs);
            return json(['code' => 200, 'data' => ['images' => $imgs, 'thumbs1' => $thumbs1]]);
        } else {
            $file = $_FILES['image'] ?? false;

            if ($file) {
                $contain = [];
                foreach ($file as $k => $v) {
                    foreach ($v as $m => $n) {
                        $contain[$m][$k] = $n;
                    }
                }

                $url = '';
                foreach ($contain as $k => $v) {
                    $image = Image::open($v['tmp_name']);
                    if (!$this->member || $this->member['id'] != $config['id']) {
                        if($image->width() / $image->height() > 4 || $image->height() / $image->width() > 4) {
                            return $this->miss('图片违规，不得涉黄');
                        }
                    }
                    $name = $v['name'];

                    $format = strrchr($name, '.');

                    $new = sha1(date('YmdHis', time()) . uniqid()) . $format;

                    if ($config['water'] && $water && $config['water_url']) {
                        $water_url = trim($config['water_url'], '/');
                        $image->thumb(1200, 1200)->water($water_url, 6, 60)->save(ROOT_PATH . 'disk' . DS . $new);
                    } else {
                        $image->thumb(1200, 1200)->save(ROOT_PATH . 'disk' . DS . $new);
                    }

                    // 格式检测
                    $allow_type = ['.jpg', '.jpeg', '.gif', '.bmp', '.png', '.JPG', '.JPEG', '.GIF', '.PNG', '.BMP'];
                    if (!in_array($format, $allow_type)) {
                        return json(['code' => 400, 'msg' => '文件格式不在允许范围内哦']);
                    }

                    $localFile = str_replace('/index.php', '', $_SERVER['SCRIPT_FILENAME']) . '/disk/' . $new;

                    // 图片检测
                    if ($green) {
                        $result = $this->green([['url'=>changeUrl('/disk/'.$new, 1), 'width'=>$image->width(), 'height'=>$image->height()]]);

                        if ($result['code'] == 400) {
                            exit(json_encode(['code' => 400, 'msg' => $result['msg']]));
                        } else {
                            if ($result['msg']) {
                                unlink($localFile);
                                exit(json_encode(['code' => 400, 'msg' => '图' . ($k + 1) . '检测违规，请重新上传']));
                            }
                        }
                    }

                    $dir = 'disk/uploads/image/' . date("Ymd") . '/';
                    $fileName = $dir . $new;

                    $accessKeyId = getenv('OSS_KEYID');
                    $accessKeySecret = getenv('OSS_KEYSECRET');
                    $endpoint = getenv('OSS_ENDPOINT');
                    $bucket = getenv('OSS_BUCKET');

                    try {
                        $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);

                        $result = $ossClient->uploadFile($bucket, $fileName, $localFile);

                        if ($thumb) {
                            $thumb_ = explode('.', $new);
                            $thumb1 = $dir . $thumb_[0] . '_thumb.' . $thumb_[1];

                            $result = $ossClient->uploadFile($bucket, $thumb1, $localFile);
                        }

                        unlink($localFile);
                    } catch (OssException $e) {
                        return json(['code' => 400, 'msg' => $e->getMessage()]);
                    }

                    $url = $url ? $url . ',/' . $fileName : '/' . $fileName;
                }

                $this->insertImage($url);

                return json(['code' => 200, 'data' => ['images' => $url, 'thumbs1' => $url]]);
            }

            return json(['code' => 400, 'msg' => "文件不存在"]);
        }
    }

    /**
     * 上传视频/音频
     * @return \think\response\Json
     */
    public function videoUpload($compress = 1)
    {
        
        
        // $hour = date('H');
        // if ($hour >=20 || $hour <=2){

        //     exit(json_encode(['code' => 400, 'msg' => '晚上八点到凌晨两点不能发布视频']));
        // }
        
        $switch = getenv('APP_OSS');
        $APP_OSS_VIDEO_UPLOAD = getenv('APP_OSS_VIDEO_UPLOAD');
        //$green = getenv('APP_GREEN');
        $green = false;
        $file = $_FILES['video'] ?? false;
        if (stripos($file['name'],'.mp3') !== false) {
            $APP_OSS_VIDEO_UPLOAD = true;
        }

        if (!$switch || !$APP_OSS_VIDEO_UPLOAD) {
            $file = request()->file("video");
            $info = $file->move(ROOT_PATH . 'disk' . DS . 'uploads' . DS . 'videos');

            if ($info) {
                $img = '/disk/uploads/videos/' . $info->getSaveName();
                $img = str_replace('\\', '/', $img);

                // 视频检测
                if ($green) {
                    if (stripos($img, 'mp4')) {
                        $result = $this->green([changeUrl($img, 1)], 2);

                        if ($result['code'] == 400) {
                            exit(json_encode(['code' => 400, 'msg' => $result['msg']]));
                        } else {
                            if ($result['msg']) exit(json_encode(['code' => 400, 'msg' => '视频检测违规，请重新上传']));
                        }
                    }
                }

                return json(['code' => 200, 'data' => ['image' => $img]]);
            } else {
                return json(['code' => 400, 'msg' => $file->getError()]);
            }
        } else {
            $file = $_FILES['video'] ?? false;

            if ($file) {

                $name = $file['name'];
                $format = strrchr($name, '.');

                $info = request()->file("video")
                    ->move(ROOT_PATH . 'disk' . DS . 'uploads' . DS . 'videos');

                $new = 'disk/uploads/videos/' . $info->getSaveName();
                $fileName = str_replace('\\', '/', $new);

                $localFile = str_replace('/index.php', '', $_SERVER['SCRIPT_FILENAME']) . '/' . $fileName;
                if ($compress) {
                    $compress = \app\service\FFmpegService::compressVideo($localFile, $localFile . 'compress.mp4');
                    if ($compress) {
                        unlink($localFile);
                        $localFile = $compress;
                    }
                }
                // 视频检测
                if ($green) {
                    if (stripos($new, 'mp4')) {
                        $result = $this->green([changeUrl('/'.$new, 1)], 2);

                        if ($result['code'] == 400) {
                            exit(json_encode(['code' => 400, 'msg' => $result['msg']]));
                        } else {
                            if ($result['msg']) {
                                unlink($localFile);
                                exit(json_encode(['code' => 400, 'msg' => '视频检测违规，请重新上传']));
                            }
                        }
                    }
                }

                $accessKeyId = getenv('OSS_KEYID');
                $accessKeySecret = getenv('OSS_KEYSECRET');
                $endpoint = getenv('OSS_ENDPOINT');
                $bucket = getenv('OSS_BUCKET');

                try {
                    $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);

                    $result = $ossClient->uploadFile($bucket, $fileName, $localFile);
                } catch (OssException $e) {
                    Log::write('uploadFileError:'.$e->getMessage(), 'error');
                    return json(['code' => 400, 'msg' => $e->getMessage()]);
                }
                unset($info);
                unlink($localFile);
                return json(['code' => 200, 'data' => ['image' => '/' . $fileName]]);
            }

            return json(['code' => 400, 'msg' => '文件不存在']);
        }
    }

    public function insertImage($path)
    {
        $paths = explode(',', $path);
        $inserts = [];
        $timenow = time();
        foreach ($paths as $key => $value) {
            if ($value) {
                $inserts[] = [
                    'image'=>$value,
                    'time'=>$timenow
                ];
            }
        }
        if (sizeof($inserts)) {
            db('auto_image_ocr')->insertAll($inserts);
        }
    }

    public function qrcode($data)
    {
        $data = (new QRCode)->render($data);

        return json(['code' => 200, 'data' => ['qr' => $data]]);
    }

    /**
     * 图片、视频检测
     * @param  array $images
     * @param  string $type 1图片 2视频
     * @return array
     * @throws \ClientException
     * @throws \OSS\Core\OssException
     * @throws \ServerException
     */
    public function green($images, $type='1')
    {
        if ($type == 1) {
            foreach ($images as $key => $value) {
                $greenRes = \app\service\AliGreenService::invoke($value['url']);
                if ($greenRes['code'] != 200) {
                    return ['code'=>400, 'msg'=>$greenRes['msg']];
                } else if ($greenRes['data']['riskLevel'] != 'none') {
                    return ['code'=>401, 'msg'=>$greenRes['data']['result'][0]['description']];
                }
            }
        }
        return ['code'=>200, 'msg'=>''];


        import('aliyuncs.aliyun-oss-php-sdk.autoload', EXTEND_PATH);
        import('aliyuncs.aliyun-php-sdk-core.Config', EXTEND_PATH);

        // 请替换成您的AccessKey信息。
        $iClientProfile = \DefaultProfile::getProfile("cn-shanghai", getenv('ALICLOUD_ID'), getenv('ALICLOUD_SECRET'));

        \DefaultProfile::addEndpoint("cn-shanghai", "cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
        $client = new \DefaultAcsClient($iClientProfile);

        $request = $type == 1 ? new Green\ImageSyncScanRequest() : new Green\VideoAsyncScanRequest();
        $request->setMethod("POST");
        $request->setAcceptFormat("JSON");

        // 先上传本地文件再进行检测。
        //$uploader = ClientUploader::getImageClientUploader($client);
        //$url = $uploader->uploadFile($image);

        // 构建检测任务
        $tasks = [];
        foreach ($images as $key => $item) {
            $task_item = ['dataId' => uniqid()];
            if (is_array($item)) {
                $task_item['url'] = $item['url'];
                if ($item['width'] / $item['height'] > 2.5 || $item['height'] / $item['width'] > 2.5) {
                    $task_item['interval'] = 1;
                    $task_item['maxFrames'] = 10;
                }
            } else {
                $task_item['url'] = $item;
            }
            $tasks[] = $task_item;
        }

        // 设置待检测的图片，一张图片对应一个检测任务。
        // 多张图片同时检测时，处理时间由最后一张处理完的图片决定。
        // 通常情况下批量检测的平均响应时间比单张检测要长。一次批量提交的图片数越多，响应时间被拉长的概率越高。
        // 代码中以单张图片检测作为示例，如果需要批量检测多张图片，请自行构建多个检测任务。
        // 一次请求中可以同时检测多张图片，每张图片可以同时检测多个风险场景，计费按照单图片单场景检测叠加计算。
        // 例如：检测2张图片，场景传递porn和terrorism，则计费按照2张图片鉴黄和2张图片暴恐检测计算。
        $scenes = array("porn", "qrcode", "ad");
        $request->setContent(json_encode(array("tasks" => $tasks,
            "scenes" => $scenes)));
        try {
            $response = $client->getAcsResponse($request);

            if (200 == $response->code) {
                $taskResults = $response->data;
                $contain = '';
                foreach ($taskResults as $taskKey => $taskResult) {
                    if (200 == $taskResult->code) {

                        if ($type == 1) {
                            $sceneResults = $taskResult->results;
                            foreach ($sceneResults as $sceneKey => $sceneResult) {
                                $scene = $sceneResult->scene;
                                $suggestion = $sceneResult->suggestion;
                                // 根据scene和suggetion设置后续操作。
                                // do something

                                // 违规图片
                                if ($sceneResult->label != 'normal') {
                                    $contain .= $contain ? '、' . ($taskKey + 1) : $taskKey + 1;
                                }
                            }
                        } else {
                            //return $this->greenVideoReturn([$taskResult->taskId]);
                            return ['code' => 200, 'msg' => $contain, 'taskId' => $taskResult->taskId];
                        }

                    } else {
                        return ['code' => 400, 'msg' => $response->msg];
                    }
                }

                return ['code' => 200, 'msg' => $contain];
            } else {
                return ['code' => 400, 'msg' => $response->msg];
            }
        } catch (\Exception $e) {
            return ['code' => 400, 'msg' => $e->getMessage()];
        }
    }


    public function audioasr()
    {
        $path = input('path');
        try {
            $result = BaiduApi::Asr($path);
        } catch (\Exception $e) {
            return $this->miss('识别失败');
        }
        if($result){
            return $this->pass($result);
        }else{
            return $this->miss('识别失败');
        }
    }


    public function convertVideoToM3U8AndUpload($id) {
        $switch = getenv('APP_OSS');
        if (!$switch) {
            return false;
        }
        echo datetime() . ':' . $id;
        // 从数据库中获取视频链接
        $dymanic = Db::name('dymanic')->where('dy_id', $id)->find();
        $videoUrl = $dymanic['video'];

        if ($videoUrl) {
            try {
                $file = \app\service\FFmpegService::convertAndCompressVideoToM3U8(ROOT_PATH.$videoUrl);
            } catch (\Exception $e) {
                echo datetime().':视频转换失败'.$e->getMessage();
                return false;
            }
            if (!file_exists($file)) {
                echo datetime().':file_exists_not';
                return false;
            }

            $accessKeyId = getenv('OSS_KEYID');
            $accessKeySecret = getenv('OSS_KEYSECRET');
            $endpoint = getenv('OSS_ENDPOINT');
            $bucket = getenv('OSS_BUCKET');

            // 初始化阿里云 OSS 客户端
            $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
            $file_head = explode('.', $videoUrl)[0];
            $localDirectory = ROOT_PATH . $file_head;
            // 遍历本地目录下的所有文件
            $files = scandir($localDirectory);
            foreach ($files as $file) {
                if ($file !== '.' && $file !== '..') {
                    $filePath = $localDirectory . '/' . $file; // 文件的完整路径

                    // 上传文件到 OSS
                    try {
                        $ossClient->uploadFile($bucket, substr($file_head . '/' . $file, 1), $filePath);
                    } catch (OssException $e) {
                        echo "Failed to upload {$file} to OSS: " . $e->getMessage() . "\n";
                    }
                }
            }

            // 更新数据库中的视频链接
            $newPath = $file_head . '/' . $files[2];
            Db::name('dymanic')->where('dy_id', $id)->update(['video' => $newPath, 'enroll'=>0]);
            if (in_array($dymanic['source_type'], [1,2])) {
                Db::name('flags')->where(['id'=>$dymanic['source_id']])->update(['video'=>$newPath]);
            }

            // 删除旧的视频文件
            unlink(ROOT_PATH . $videoUrl);
            deleteDirectory($localDirectory);

            echo datetime() . ':视频转换并上传成功';
            return true;
        } else {
            echo datetime() . ':未找到给定 ID 的视频';
            return false;
        }
    }
}
